/* 
 * File:   ObjetoGrafico.hpp
 * Author: cesar
 *
 * Clase abstracta que define las propiedades de un objeto grafico y
 * las funciones para su interaccion
 */

#ifndef OBJETOGRAFICO_HPP
#define	OBJETOGRAFICO_HPP

#define SUELO -40 //valor del suelo en el eje Y
#define NUM_BUFFERS 1 //buffers de sonido
#define NUM_FUENTES 1 //fuentes de sonido
#define NUM_ENVIRONMENTS 1 //cantidad de entornos de sonido

#include <GL/glut.h>
#include <iostream>
#include <cmath>
#include <AL/al.h>
#include <AL/alut.h>

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

class ObjetoGrafico {
public:

    /**
     * Constructor de la Clase ObjetoGrafico
     * 
     * @param pos_x : Posicion en el eje X.
     * @param pos_y : Posicion en el eje Y.
     * @param pos_z : Posicion en el eje Z.
     */
    ObjetoGrafico(GLfloat pos_x = 0.0, GLfloat pos_y = 0.0, GLfloat pos_z = 0.0);


    /**Metodo virtual dibujar que debe implementar cada clase
     * que extienda de esta.
     */
    virtual void dibujar();


    /**
     * Permite asignar la posicion de la fuente de luz de la escena para construir
     * la matriz de sombra.
     * 
     * @param pos_x : Posicion en el eje X de la fuente de luz
     * @param pos_y : Posicion en el eje Y de la fuente de luz
     * @param pos_z : Posicion en el eje Z de la fuente de luz
     */
    void setPosicionLuz(GLfloat pos_x, GLfloat pos_y, GLfloat pos_z);


    /**
     * Permite mover a la derecha el objeto
     */
    void moverDer();


    /**
     * Permite mover a la izquierda el objeto
     */
    void moverIzq();


    /**
     * Permite mover hacia arriba el objeto
     */
    void moverArriba();


    /**
     * Permite mover hacia abajo el objeto
     */
    void moverAbajo();

    /**
     * Permite mover al frente el objeto
     */
    void moverFrente();


    /**
     * Permite mover hacia atras el objeto
     */
    void moverAtras();

    /**
     * Esta funcion retorma la posicion en el eje X del objeto.
     * @return La posicion en el eje X del objeto
     */
    GLfloat getX();


    /**
     * Esta funcion retorma la posicion en el eje Y del objeto.
     * @return La posicion en el eje Y del objeto
     */
    GLfloat getY();

    /**
     * Esta funcion retorma la posicion en el eje Z del objeto.
     * @return La posicion en el eje Z del objeto
     */
    GLfloat getZ();


    /**
     * Indicar la velocidad del objeto.
     * 
     * @param s : la velocidad que va a tener el objeto.
     */
    void setSpeed(GLfloat);



    /**
     * Esta funcion permite obtener los coeficientes de la ecuacion del plano
     * a partir de tres puntos.
     * 
     * @param p1 : El primer punto del plano.
     * @param p2 : El segundo punto del plano.
     * @param p3 : El tercer punto del plano.
     * @return Los coeficientes de la ecuacion del plano.
     */
    GLfloat * calcularPlano(GLfloat* p1, GLfloat* p2, GLfloat* p3);




    /**
     * Calcular la distacia del objeto a un punto en el espacio.
     * 
     * @param pos_x : La posicion del punto en el eje X.
     * @param pos_y : La posicion del punto en el eje Y.
     * @param pos_z : La posicion del punto en el eje Z.
     * @return La distancia al punto especificado
     */
    GLfloat distanciaA(GLfloat pos_x, GLfloat pos_y, GLfloat pos_z);


protected:


    /**
     * Este metodo permite calcular la matriz de Sombra, usada para proyectar la
     * sombra del objeto sobre un plano.
     * 
     * @param plane : Los coeficientes de la ecuacion del plano, donde se quiere
     *              proyectar la sombra.
     */
    void CalcMatrizSombra(GLfloat* plane);


    /**
     * Este metodo permite activar las configuraciones de blending y proyecciones
     * para poder dibujar sombras mediante la matriz de proyeccion. Todo lo que se
     * dibuje despues  de esta llamada estara afectado por la matriz de sombra.
     */
    void activarModoSombra();


    /**
     * Este metodo permite desactivar la configuracion de matriz de sombra.
     */
    void desactivarModoSombra();

    /**
     * Este metodo permite inicializar las configuraciones de Sonido del
     * objeto grafico.
     */
    void initSound();


    /**
     * Permite cargar el sonido que le corresponde al objeto.
     * 
     * @param nombre_sonido : Nombre del archivo de sonido.
     * @param loop : Indica si el sonido debe repetirse o debe tener una unica ocurrencia.
     */
    void cargarSonido(char * nombre_sonido, ALboolean loop);

    GLfloat x; //posicion en x
    GLfloat y; //posicion en y
    GLfloat z; //posicion en z
    GLfloat * color; // color del objeto
    GLfloat speed; //velocidad del objeto
    GLfloat material_ambient[3]; //material ambiental
    GLfloat material_difuso[3]; //material difuso
    GLfloat material_especular[3]; //material especular
    GLfloat material_emision[3]; //material emision
    GLfloat material_brillo[1]; //material brillo
    GLfloat posicion_luz[4]; //posicion de la fuente de luz de sombra
    GLfloat matriz_sombra[4][4]; //matriz para el calculo de sombras
    ALfloat * listenerPos; //posicion del oyente
    ALfloat * listenerVel; //velocidad del oyente
    ALfloat * listenerOri; // orientacion del oyecte
    ALfloat * sourcesPos; // posicion de la fuente de sonido
    ALfloat * sourcesVel; //velocidad de la fuente de sonido
    ALuint buffer[NUM_BUFFERS]; //buffer de sonido
    ALuint source[NUM_FUENTES]; // fuentes de sonido
    int ancho_pantalla; // ancho de la pantalla
    int alto_pantalla; // alto de la pantalla



};

#endif	/* OBJETOGRAFICO_HPP */

